//---------------------------------------------------------------------
//  This file is part of the Background Motion solution.
// 
//  Copyright (C) Mindscape (TM).  All rights reserved.
//  http://www.mindscape.co.nz
// 
//  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Security.Principal;
using System.Threading;

using Mindscape.BackgroundMotion.Core;
using Mindscape.BackgroundMotion.Model;
using Mindscape.BackgroundMotion.Model.Security;

namespace Mindscape.BackgroundMotion.Website.Infrastructure
{
  /// <summary>
  /// Base class for all application controllers in the system
  /// </summary>
  public class ControllerBase : IController
  {
    /// <summary>
    /// Returns the currently authenticated member
    /// </summary>
    public Member CurrentMember
    {
      get
      {
        BackgroundMotionIdentity currentIdentity = (Thread.CurrentPrincipal != null)
          ? Thread.CurrentPrincipal.Identity as BackgroundMotionIdentity
          : null;

        return (currentIdentity != null)
          ? currentIdentity.Member
          : null;
      }
    }

    /// <summary>
    /// Indicates if there is a currently authenticated member on the executing request
    /// </summary>
    public bool IsLoggedIn
    {
      get { return (GetSession<int?>(Constants.Session.MemberId) != null); }
    }

    /// <summary>
    /// Redirects to a nominated URL
    /// </summary>
    /// <param name="url">The URL to redirect to</param>
    public void RedirectTo(string url)
    {
      Context.RedirectTo(url);
    }

    /// <summary>
    /// Redirects to a nominated URL and querystring
    /// </summary>
    /// <param name="url">The URL to redirect to</param>
    /// <param name="parameters">The querystring parameters to pass</param>
    public void RedirectTo(string url, params string[] parameters)
    {
      Context.RedirectTo(url, parameters);
    }

    /// <summary>
    /// Assigns a value to the session container under a nominated key
    /// </summary>
    /// <param name="key">The key to the object</param>
    /// <param name="value">The object</param>
    /// <typeparam name="T">The generic type of the assigned object</typeparam>
    public void SetSession<T>(string key, T value)
    {
      Context.SetSession(key, value);
    }

    /// <summary>
    /// Returns a value held in the session container
    /// </summary>
    /// <param name="key">The key to the object</param>
    /// <returns>
    /// An object of type T which is known by the requested key
    /// </returns>
    /// <typeparam name="T">The generic type of the returned object</typeparam>
    public T GetSession<T>(string key)
    {
      return Context.GetSession<T>(key);
    }

    /// <summary>
    /// Returns a value held in the "query string" parameter container
    /// </summary>
    /// <param name="key">The key to the object</param>
    /// <returns>
    /// An object of type T which is known by the requested key
    /// </returns>
    /// <typeparam name="T">The generic type of the returned object</typeparam>
    public T GetParameter<T>(string key)
    {
      return Context.GetParameter<T>(key);
    }

    /// <summary>
    /// Removes an object from the session container which matches a nominated key
    /// </summary>
    /// <param name="key">The key to the object</param>
    public void RemoveSession(string key)
    {
      Context.RemoveSession(key);
    }

    /// <summary>
    /// Assigns a new cookie to the cookies collection
    /// </summary>
    /// <param name="name">The name of the cookie</param>
    /// <param name="value">The value of the cookie</param>
    /// <param name="expires">The time at which the cookie expires</param>
    public void AddCookie(string name, string value, DateTime expires)
    {
      Context.AddCookie(name, value, expires);
    }

    /// <summary>
    /// Removes a cookie from the cookies collection by a nominated name
    /// </summary>
    /// <param name="name">The name of the cookie</param>
    public void RemoveCookie(string name)
    {
      Context.RemoveCookie(name);
    }

    /// <summary>
    /// The principal which is currently authorised
    /// </summary>
    /// <value></value>
    public IPrincipal Principal
    {
      set
      {
        Context.User = value;

        Thread.CurrentPrincipal = value;
      }
    }

    /// <summary>
    /// Returns a cookie value from the cookies collection by a nominated name
    /// </summary>
    /// <param name="name">The name of the cookie</param>
    /// <returns>
    /// The value of the cookie which is known by the nominated name
    /// </returns>
    public string GetCookie(string name)
    {
      return Context.GetCookie(name);
    }

    /// <summary>
    /// Returns the Path and Querystring of the current request
    /// </summary>
    /// <value></value>
    public string RequestPathAndQuery
    {
      get { return Context.RequestPathAndQuery; }
    }

    /// <summary>
    /// Returns the Absolute Path of the current request
    /// </summary>
    /// <value></value>
    public string RequestAbsolutePath
    {
      get { return Context.RequestAbsolutePath; }
    }

    /// <summary>
    /// Gets the current context
    /// </summary>
    private static IContext Context
    {
      get { return ServiceLocator.Get<IContext>(); }
    }
  }
}